
const socket_io = require('socket.io');


const socketio = (() => {
    // 单例,保证只有一个socketio对象
    let obj = { _io: null };

    Object.defineProperty(obj, 'io', {
        set(io) {
            io.on('connection', function(socket) {


                const objToStr = Object.prototype.toString;

                // console.log(socket.id, 'link')
                io.connectUser = io.connectUser || {};

                const userID = socket.handshake.query.user_id;
                if (userID === '-1') {
                    socket.disconnect(true);
                    return;
                }

                if (objToStr.call(io.connectUser[userID]) === '[object Array]') {
                    io.connectUser[userID].push(socket.id);
                } else {
                    io.connectUser[userID] = [socket.id];
                }


                socket.on('joinRoom', function(roomID) {
                    const roomIDType = objToStr.call(roomID);
                    if (roomIDType === '[object Array]') {
                        roomID.forEach(room_id => {
                            socket.join(`room${room_id}`); 
                        });
                    } else if (roomIDType === '[object String]' || roomIDType === '[object Number]') {
                        socket.join(`room${room_id}`); 
                    }
                });

                socket.on('disconnect', function() {
                    // console.log('disconnect')
                    let index = -1;
                    for (let i = 0; i < io.connectUser[userID].length; i++) {
                        if (io.connectUser[userID][i] === socket.id) {
                            index = i;
                            break;
                        }
                    }
                    io.connectUser[userID].splice(index, 1);
                    // console.log(socket.id, 'diconnect')
                });


                // 使在外部可使用当前socket触发事件
                io.emit = (event, data) => {
                    socket.emit(event, data);
                };
                io.toEmit = (event, toTarget, data) => {
                    if (!toTarget) return;
                    if (objToStr.call(toTarget) === '[object Array]') {
                        for (let i = 0; i < toTarget.length; i++) {
                            socketio().to(toTarget[i]).emit(event, data);
                        }
                    } else {
                        socketio().to(toTarget).emit(event, data);
                    }
                    if (event === 'quitLog') {
                        // 触发quitLog代表有不同session登录,则把之前的session登录用户清除
                        let has = false;
                        for (let i = 0; i < socketio().connectUser[userID].length; i++) {
                            if (socketio().connectUser[userID][i] === socket.id) {
                                has = true;
                                break;
                            }
                        }
                        if (!has) {
                            socketio().connectUser[userID] = [];
                        }
                    }
                }
            });
            
            this._io = io;
        },
        get() {
            return this._io
        }
    })
    
    return server => obj.io || (obj.io = socket_io(server), obj.io);
})();


module.exports = socketio;

